#ifndef __INCLUDED_CBL_REFERENCEPTR_H__
#error "CBL_ReferencePtr.hpp must not be used directly. Use CBL_ReferencePtr.h instead."
#else
#ifndef __INCLUDED_CBL_REFERENCEPTR_HPP__
#define __INCLUDED_CBL_REFERENCEPTR_HPP__

template <typename TType>
CReferencePtr<TType>::CReferencePtr()
	: m_pObject(NULL)
	, m_pReferenceCounter(NULL)
{
}

// -------------------------------------------------------------------------------------

template <typename TType>
CReferencePtr<TType>::CReferencePtr(TType*& _rpObject)
	: m_pObject(NULL)
	, m_pReferenceCounter(NULL)
{
	if (_rpObject != NULL)
    {
	    m_pObject = _rpObject;
    	_rpObject = NULL;
        m_pReferenceCounter = new int32(1);
    }
}

// -------------------------------------------------------------------------------------

template <typename TType>
CReferencePtr<TType>::CReferencePtr(const CReferencePtr<TType>& _rCopy)
	: m_pObject(static_cast<TType*>(_rCopy.GetObject()))
	, m_pReferenceCounter(const_cast<int32*>(_rCopy.GetReferenceCounter()))
{
    if (m_pReferenceCounter)
        ++(*m_pReferenceCounter);
}

// -------------------------------------------------------------------------------------

template <typename TType>
template <typename TType2>
CReferencePtr<TType>::CReferencePtr(const CReferencePtr<TType2>& _rCopy)
	: m_pObject(static_cast<TType*>(_rCopy.GetObject()))
	, m_pReferenceCounter(const_cast<int32*>(_rCopy.GetReferenceCounter()))
{
    if (m_pReferenceCounter)
        ++(*m_pReferenceCounter);
}

// -------------------------------------------------------------------------------------

template <typename TType>
CReferencePtr<TType>::~CReferencePtr()
{
    Release();
}

// -------------------------------------------------------------------------------------

template <typename TType>
CB_FORCEINLINE CReferencePtr<TType>& CB_INLINE_ATTR CReferencePtr<TType>::operator = (TType*& _rpNewObject)
{
    Release();
    
    if (_rpNewObject)
    {
    	m_pObject = _rpNewObject;
    	_rpNewObject = NULL;
    	m_pReferenceCounter = new int32(1);
    }
    
    return *this;
}

// -------------------------------------------------------------------------------------

template <typename TType>
CB_FORCEINLINE CReferencePtr<TType>& CB_INLINE_ATTR CReferencePtr<TType>::operator = (const CReferencePtr<TType>& _rCopy)
{
    Release();
    
    m_pObject = _rCopy.m_pObject;
    m_pReferenceCounter = _rCopy.m_pReferenceCounter;
    
    if (m_pReferenceCounter)
        ++(*m_pReferenceCounter);
    
    return *this;
}

// -------------------------------------------------------------------------------------

template <typename TType>
template <typename TType2>
CB_FORCEINLINE CReferencePtr<TType>& CB_INLINE_ATTR CReferencePtr<TType>::operator = (const CReferencePtr<TType2>& _rCopy)
{
    Release();
    
    m_pObject = static_cast<TType*>(_rCopy.m_pObject);
    m_pReferenceCounter = _rCopy.m_pReferenceCounter;
    
    if (m_pReferenceCounter)
        ++(*m_pReferenceCounter);
    
    return *this;
}

// -------------------------------------------------------------------------------------

template <typename TType>
CB_FORCEINLINE void CB_INLINE_ATTR CReferencePtr<TType>::Release()
{
    if (m_pReferenceCounter)
    {
        --(*m_pReferenceCounter);
        if (*m_pReferenceCounter == 0)
        {
            delete m_pObject;
            delete m_pReferenceCounter;
        }
        
        m_pReferenceCounter = NULL;
    }
    
    m_pObject = NULL;
}

#endif
#endif